package com.dctp.common.utils;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import java.sql.Time;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

public class MarketTimeUtil {

    public static class TimeRange {
        private final LocalTime start;
        private final LocalTime end;
        private final boolean crossDay;

        public TimeRange(LocalTime start, LocalTime end, boolean crossDay) {
            this.start = start;
            this.end = end;
            this.crossDay = crossDay;
        }

        public boolean isInRange(ZonedDateTime now,String countryCode) {
            ZonedDateTime startDateTime = now.with(start);
            ZonedDateTime endDateTime = now.with(end);
            if (crossDay) {
                if ("US".equals(countryCode)) {
                    if (now.toLocalTime().isBefore(LocalTime.of(18,0))) {
                        //与endDate同一天
                        startDateTime = startDateTime.minusDays(1);
                    }else {
                        //与startDate同一天
                        endDateTime = endDateTime.plusDays(1);
                    }
                }else if ("HK".equals(countryCode)) {
                    LocalTime nowTime = now.toLocalTime();
                    if (nowTime.isAfter(LocalTime.of(0,0))
                            && nowTime.isBefore(LocalTime.of(3,0))) {
                        //凌晨0-3点
                        startDateTime = startDateTime.minusDays(1);
                    }else if (nowTime.isBefore(LocalTime.of(23,59,59)) && nowTime.isAfter(LocalTime.of(17,15))) {
                        //17:15-00:00
                        endDateTime = endDateTime.plusDays(1);
                    }
                }
            }
            return now.isAfter(startDateTime) && now.isBefore(endDateTime);
        }
    }


    public static List<TimeRange> getTradingSessions(String marketCode) {
        List<Record> records = Db.find("SELECT * FROM dctp_market_time WHERE enabled = 1 AND market_code = ?", marketCode);
        List<TimeRange> result = new ArrayList<>();
        for (Record r : records) {

            Time startTimeSql = r.get("start_time");
            Time endTimeSql = r.get("end_time");

            LocalTime start = startTimeSql.toLocalTime();
            LocalTime end = endTimeSql.toLocalTime();

            boolean crossDay = r.getBoolean("cross_day");
            result.add(new TimeRange(start, end, crossDay));
        }
        return result;
    }

    public static boolean isInTradingSession(String marketCode,String countryCode, ZoneId zoneId, ZonedDateTime now) {
        ZonedDateTime exchangeNow = now.withZoneSameInstant(zoneId);
        for (TimeRange r : getTradingSessions(marketCode)) {
            if (r.isInRange(exchangeNow,countryCode)) {
                return true;
            }
        }
        return false;
    }

    public static boolean canRequest(String marketCode, String countryCode) {

        ZoneId zoneId = HolidayUtil.getZoneIdByCountry(countryCode);
        ZonedDateTime now = ZonedDateTime.now(zoneId);

        // 是否在交易时间段
        boolean isTradingTime = isInTradingSession(marketCode,countryCode,zoneId, now);
        // 用调整后的时间判断交易日
        boolean isTradingDay = HolidayUtil.isTradingDay(countryCode, now);

        return isTradingDay && isTradingTime;
    }
}
